﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;


public class L_DLLInfo : IDisposable
{
    public L_DLLInfo(string name)
    {
        this.Name = name;
    }

    public string Name;
    public MemoryStream DllStream;
    public MemoryStream PDBStream;

    public void Dispose()
    {
        DllStream?.Dispose();
        PDBStream?.Dispose();
    }
}

public static class LoadUtils
{
    static Dictionary<string, L_DLLInfo> dllDics = new Dictionary<string, L_DLLInfo>();

    public static async Task<L_DLLInfo> LoadAsync(string f)
    {
        if (dllDics.ContainsKey(f))
        {
            return dllDics[f];
        }

        var dllBytes = await LoadFileAsync(f + ".dll");
        var pdbBytes = await LoadFileAsync(f + ".pdb");

        L_DLLInfo l = new L_DLLInfo(f);
        l.DllStream = new MemoryStream(dllBytes);
        l.PDBStream = new MemoryStream(pdbBytes);
        dllDics.Add(f, l);
        return l;
    }

    public static Task<byte[]> LoadFileAsync(string f)
    {
        var tcs = new TaskCompletionSource<byte[]>();
        UnityWebRequest unityWebRequest = UnityWebRequest.Get(FileUtils.dllPath + "/" + f);

        unityWebRequest.SendWebRequest().completed += operation =>
        {
            var unityWebRequestAsyncOperation = operation as UnityWebRequestAsyncOperation;
            if (unityWebRequestAsyncOperation.webRequest.isHttpError ||
                unityWebRequestAsyncOperation.webRequest.isNetworkError)
            {
                tcs.TrySetResult(null);
            }
            else
            {
                tcs.TrySetResult(unityWebRequestAsyncOperation.webRequest.downloadHandler.data);
            }
        };

        return tcs.Task;
    }

    public static void ClearDLLStream()
    {
        foreach (var VARIABLE in dllDics)
        {
            VARIABLE.Value.Dispose();
        }
        dllDics.Clear();
    }
}